package io.renren.modules.member.controller;

import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.validator.ValidatorUtils;
import io.renren.modules.member.dto.ExamDto;
import io.renren.modules.member.entity.ExamEntity;
import io.renren.modules.member.enums.SportEnums;
import io.renren.modules.member.service.ExamMiddleHistoryService;
import io.renren.modules.member.service.ExamService;
import io.renren.modules.member.service.ExcelService;
import io.renren.modules.oss.service.SysOssService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.*;

/**
 * 测试成绩
 *
 * @author Mark 军事体育训练考核系统
 */
@RestController
@RequestMapping("exam/exam")
public class ExamController {

    private final Logger logger = LoggerFactory.getLogger(ExamController.class);

    @Autowired
    private ExamService examService;

    @Autowired
    private SysOssService sysOssService;

    @Autowired
    private ExcelService excelService;

    @Autowired
    private ExamMiddleHistoryService historyService;

    @Autowired
    private Environment env;

    private static final String OUT_FILE_NAME = "人员考核成绩表";

    private static final String OUT_FILE_NAME_TEMP = "人员考核成绩表模板.xlsx";

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("exam:exam:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = examService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("exam:exam:info")
    public R info(@PathVariable("id") Long id){
        ExamEntity exam = examService.getById(id);

        return R.ok().put("exam", exam);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("exam:exam:save")
    public R save(@RequestBody ExamEntity exam){
        //校验类型
        ValidatorUtils.validateEntity(exam);
        examService.saveOrUpdateExam(exam);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("exam:exam:update")
    public R update(@RequestBody ExamEntity exam){
        //校验类型
        ValidatorUtils.validateEntity(exam);
        examService.saveOrUpdateExam(exam);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("exam:exam:delete")
    public R delete(@RequestBody Long[] ids){
        examService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    @RequestMapping("/downloadExTemp")
    @RequiresPermissions("exam:exam:upload")
    public String downloadExTemp(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        String path = ResourceUtils.getURL("classpath:").getPath();
        String path = java.net.URLDecoder.decode(env.getProperty("download.excel"), "utf-8");
        File file = new File(path, "excel/人员考核成绩模板.xlsx");
//        String path = this.getClass().getResource("/excel/人员考核成绩模板.xlsx").getPath();
//        path = java.net.URLDecoder.decode(path,"utf-8");
//        File file = new File(path);
        sysOssService.download(request, response, file, OUT_FILE_NAME_TEMP);
        return null;
    }

    @RequestMapping("/upload/{type}")
    @RequiresPermissions("exam:exam:upload")
    public R upload(@RequestParam("file") MultipartFile file, @PathVariable("type") String type) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        //上传文件
        sysOssService.upload(file);
        String originalFilename = file.getOriginalFilename();
        logger.info("上传文件名称:{}", originalFilename);
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (StringUtils.isNotBlank(suffix) &&
                (StringUtils.equals(suffix.toLowerCase(), ".xls") || StringUtils.equals(suffix.toLowerCase(), ".xlsx"))) {
            // 解析excel
            InputStream inputStream = file.getInputStream();
            List<List<Object>> list = excelService.getBankListByExcel(inputStream, file.getOriginalFilename());
            logger.info("excel解析成功");
            inputStream.close();
            // 各属性与Excel的列对应关系
            Map<String, Integer> position = getExcelPosition(type);
            examService.batchSaveExcelExam(list, position);
        } else if (StringUtils.isNotBlank(suffix) && StringUtils.equals(suffix.toLowerCase(), ".txt")) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
            List<String> list = new ArrayList<>();
            String lineStr = null;
            while ((lineStr = reader.readLine()) != null) {
                logger.info("文本文件：{}", lineStr);
                list.add(lineStr);
            }
            reader.close();
            examService.batchStrSave(list);
            logger.info("文本文件OK");
        }


        return R.ok().put("msg", "学员考试登记成功");
    }

    private Map<String, Integer> getExcelPosition(String type) {
        Map<String, Integer> position = new HashMap<>();
        if (StringUtils.equals(type, "1")) {
            position.put("examDate", 0);
            position.put("studentCode", 1);
            position.put("height", 3);
            position.put("weight", 4);
            position.put("leadUp", 5);
            position.put("crankRrm", 6);
            position.put("pushUp", 7);
            position.put("sitUp", 8);
            position.put("snakeRun", 9);
            position.put("middleRun", 10);
        }
        return position;
    }

    @RequestMapping("/download")
    @RequiresPermissions("exam:exam:download")
    public String download(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("name", request.getParameter("name"));
        param.put("studentCode", request.getParameter("studentCode"));
        List<String> titles = new ArrayList();
        List<List<String>> excelValues =  examService.downExcelByCondition(param, titles);
        excelService.writeExcel(request, response, OUT_FILE_NAME, titles, excelValues);
        return null;
    }

    /**
     * 接口上传单项成绩
     */
    @RequestMapping("/achieve")
    public R save(@RequestBody ExamDto dto){

        if (StringUtils.isBlank(dto.getStudentCode())
                || StringUtils.isBlank(dto.getType())
                || Objects.isNull(dto.getDate())
                || Objects.isNull(dto.getAchieve())) {
            return R.error().put("msg", "学籍号，项目类型，时间, 成绩不能为空");
        }
        ExamEntity entity = null;
        if (SportEnums.MIDDLE_RUN.getCode().equals(dto.getType())) {
            if (Objects.isNull(dto.getCircle()) || dto.getCircle() < 1) {
                return R.error().put("msg", "圈数必须大于0");
            }
            if (Objects.nonNull(dto.getTotalCircle()) && dto.getTotalCircle().equals(dto.getCircle())) {
                entity = examService.saveOneAchiv(dto);
                // 保存中长跑历史
                historyService.save(dto, Objects.nonNull(entity) ? entity.getMiddleRunScore() : BigDecimal.ZERO);
            } else {
                historyService.save(dto, BigDecimal.ZERO);
            }
        } else {
            logger.info("成绩入参是：{}", dto.toString());
            entity = examService.saveOneAchiv(dto);
        }

        return R.ok().put("data", entity);
    }

    /**
     * 文件上传所有成绩
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/upload/achieve")
    public R uploadIdCode(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
        List<String> list = new ArrayList<>();
        String lineStr = null;
        while ((lineStr = reader.readLine()) != null) {
            logger.info("文本文件：{}", lineStr);
            list.add(lineStr);
        }
        reader.close();
        examService.batchStrSave(list);
        logger.info("文本文件OK");

        return R.ok().put("msg", "成绩文件上传成功");
    }

}
